#ifndef __COMM_HPP__
#define __COMM_HPP__

#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <cassert>

using namespace std;

#define Mode 0666
#define Path "./fifo"

class Fifo
{
public:
  Fifo(const string &path = Path) : _path(path)
  {
    umask(0);
    int n = mkfifo(_path.c_str(), Mode);
    if (n == 0)
    {
      cout << "mkfifo success" << endl;
    }
    else
    {
      cerr << "mkfifo failed, errno: " << errno << ", errstring: " << strerror(errno) << endl;
    }
  }
  ~Fifo()
  {
    int n = unlink(_path.c_str());
    if (n == 0)
    {
      cout << "remove fifo file " << _path << " success" << endl;
    }
    else
    {
      cerr << "remove failed, errno: " << errno << ", errstring: " << strerror(errno) << endl;
    }
  }

private:
  string _path; // 文件路径+文件名
};

// 利用管道提供进程间协同机制
class Sync
{
public:
  Sync() : rfd(-1), wfd(-1)
  {
  }
  void OpenReadOrDie()
  {
    rfd = open(Path, O_RDONLY);
    if (rfd < 0)
      exit(1);
  }
  void OpenWriteOrDie()
  {
    wfd = open(Path, O_WRONLY);
    if (wfd < 0)
      exit(1);
  }

  // 实现进程间协同机制，服务端用
  bool Wait()
  {
    bool ret = true;
    uint32_t c = 0;
    ssize_t n = read(rfd, &c, sizeof(uint32_t));
    if (n == sizeof(uint32_t))
    {
      std::cout << "server wakeup, begin read shm..." << std::endl;
    }
    else if (n == 0)
    {
      ret = false;
    }
    else
    {
      return false;
    }
    return ret;
  }

  // 实现进程间协同机制，客户端用
  void Wakeup()
  {
    uint32_t c = 0;
    ssize_t n = write(wfd, &c, sizeof(c));
    assert(n == sizeof(uint32_t));

    std::cout << "wakeup server..." << std::endl;
  }
  ~Sync() {}

private:
  int rfd;
  int wfd;
};

#endif
